﻿#include "stdafx.h"
#include "AirIM.h"

AirIM::AirIM(QWidget *parent, Qt::WindowFlags flags)
    : QMainWindow(parent, flags),
      m_socket(nullptr)
{
	ui.setupUi(this);
	ui.stackedWidget->setAttribute(Qt::WA_TranslucentBackground, true);
    setAttribute(Qt::WA_QuitOnClose);
    setAttribute(Qt::WA_TranslucentBackground, true);
    //setAttribute(Qt::WA_NoSystemBackground, true);

#ifdef Q_OS_WIN32
    // 去掉窗口标题栏方式
    setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint/* | Qt::WindowStaysOnTopHint*/);
	// 设置标题
	//ui.title->setText(tr("<font color=white>&nbsp;YY 0.1</font>"));
    ui.titleLabel->setPixmap(QPixmap(tr(":/MainPanel/Main_Title")));
    ui.maximizeSysButton->setProperty("windowMaxsized", false);
    setProperty("isWin32", true);
    ui.centralWidget->setContentsMargins(6, 6, 6, 6);
#else
    ui.titleLabel->hide();
    ui.minisizeSysButton->hide();
    ui.maximizeSysButton->hide();
    ui.closeSysButton->hide();
    setProperty("isWin32", false);
#endif

#ifdef Q_OS_WIN32
	// 创建托盘图标
    m_trayIcon = new QSystemTrayIcon(this);
	m_trayIcon->setIcon(QIcon(":/Air.ico"));
	m_trayIcon->setToolTip(tr("Air"));
	m_trayIcon->show();
	//添加托盘的鼠标事件  
	QObject::connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayActived(QSystemTrayIcon::ActivationReason)));
	// Action
	QAction *actionSetting = new QAction("设置(&S)", this);
	QAction *actionOpenMain = new QAction(QIcon(":/Air.ico"), tr("打开主界面(&O)"), this);
	connect(actionOpenMain, SIGNAL(triggered()), this, SLOT(taryOpenMain()));
	QAction *actionQuit = new QAction(tr("退出(&E)"), this);
	connect(actionQuit, SIGNAL(triggered()), this, SLOT(trayClose()));
	// 主界面托盘菜单
	m_trayIconMenu = new QMenu(this);
	m_trayIconMenu->addAction(QIcon(":/Resources/Status/Big/online.png"), tr("Online"));
	m_trayIconMenu->addAction(QIcon(":/Resources/Status/Big/away.png"), tr("Away"));
	m_trayIconMenu->addAction(QIcon(":/Resources/Status/Big/busy.png"), tr("Busy"));
	m_trayIconMenu->addAction(QIcon(":/Resources/Status/Big/offline.png"), tr("Offline"));
	m_trayIconMenu->addSeparator();
	m_trayIconMenu->addAction(actionSetting);
	m_trayIconMenu->addSeparator();
	m_trayIconMenu->addAction(actionOpenMain);
	m_trayIconMenu->addSeparator();
	m_trayIconMenu->addAction(actionQuit);
	m_trayIcon->setContextMenu(m_trayIconMenu);
#endif

	m_statusMenu = new QMenu(this);
	m_statusMenu->addAction(QIcon(":/Resources/Status/Big/online.png"), tr("Online"));
	m_statusMenu->addSeparator();
	m_statusMenu->addAction(QIcon(":/Resources/Status/Big/away.png"), tr("Away"));
	m_statusMenu->addAction(QIcon(":/Resources/Status/Big/busy.png"), tr("Busy"));
	m_statusMenu->addSeparator();
	m_statusMenu->addAction(QIcon(":/Resources/Status/Big/offline.png"), tr("Offline"));
	ui.statusButton->setMenu(m_statusMenu);
	ui.statusButton->setIcon(QIcon(":/Resources/Status/Big/online.png"));
	ui.statusButton->setText(tr("  "));

	QPainterPath path;
	QRectF rect = QRectF(0, 0, m_statusMenu->sizeHint().width(), m_statusMenu->sizeHint().height());
	path.addRoundedRect(rect, 2, 2);
	QPolygon polygon = path.toFillPolygon().toPolygon();		// 获得这个路径上的所有的点
	QRegion region(polygon);									// 根据这个点构造这个区域
	m_statusMenu->setMask(region);

    ui.portraitLabel->setPixmap(QPixmap(":/Resources/UserFace/face.jpg"));
    ui.portraitLabel->setScaledContents(true);
	ui.herderShortcutsButton->setIcon(QIcon(":/Resources/Expand/mail.png"));
	//ui.messageBoxButton->setIcon(QIcon(":/Resources/msgBox.png"));
	ui.searchEdit->setPlaceholderText(tr("Search contacts"));
    ui.searchEdit->setClearButtonEnabled(true);

    QObject::connect(ui.signatureEdit, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
    QObject::connect(ui.signatureEdit, SIGNAL(editingFinished()), this, SLOT(editingFinished()));
	QButtonGroup* group = new QButtonGroup(this);
	group->addButton(ui.tabButtonRecentContacts);
	group->addButton(ui.tabButtonContacts);
	group->addButton(ui.tabButtonGroups);

	// ContactsWidget
	ContactsTreeStyledItemDelegate* contactsStyleDelegate = new ContactsTreeStyledItemDelegate(ui.treeWidgetContacts);
	ui.treeWidgetContacts->setItemDelegate(contactsStyleDelegate);
	ui.treeWidgetContacts->setRootIsDecorated(false);
	ui.treeWidgetContacts->setIndentation(0);
	ui.treeWidgetContacts->setExpandsOnDoubleClick(false);
	QObject::connect(ui.treeWidgetContacts, SIGNAL(clicked(const QModelIndex&)), this, SLOT(contactsTreeWidget_clicked(const QModelIndex&)));
    QObject::connect(ui.treeWidgetContacts, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(contactsTreeWidget_doubleClicked(const QModelIndex&)));

	{
		// 加载联系人
		QTreeWidgetItem *groupItem = new QTreeWidgetItem();
		groupItem->setText(0, tr("我的好友"));
		groupItem->setData(0, Qt::UserRole + 1, 0);
		QTreeWidgetItem *contactsItem = new QTreeWidgetItem();
		contactsItem->setText(0, tr("好友1"));
		contactsItem->setIcon(0, QIcon(tr(":/Resources/UserFace/face.jpg")));
		contactsItem->setData(0, Qt::UserRole + 1, 1);
		groupItem->addChild(contactsItem);
		contactsItem = new QTreeWidgetItem();
		contactsItem->setText(0, tr("好友2"));
		contactsItem->setIcon(0, QIcon(tr(":/Resources/UserFace/face.jpg")));
		contactsItem->setData(0, Qt::UserRole + 1, 1);
		groupItem->addChild(contactsItem);
		ui.treeWidgetContacts->addTopLevelItem(groupItem);

		groupItem = new QTreeWidgetItem();
		groupItem->setText(0, tr("陌生人"));
		groupItem->setData(0, Qt::UserRole + 1, 0);
		ui.treeWidgetContacts->addTopLevelItem(groupItem);
		contactsItem = new QTreeWidgetItem();
		contactsItem->setText(0, tr("陌生人1"));
		contactsItem->setIcon(0, QIcon(tr(":/Resources/UserFace/face.jpg")));
		contactsItem->setData(0, Qt::UserRole + 1, 1);
		groupItem->addChild(contactsItem);
		contactsItem = new QTreeWidgetItem();
		contactsItem->setText(0, tr("陌生人3"));
		contactsItem->setIcon(0, QIcon(tr(":/Resources/UserFace/face.jpg")));
		contactsItem->setData(0, Qt::UserRole + 1, 1);
		groupItem->addChild(contactsItem);
		

		for (int k = 0; k < 10; k++)
		{
			contactsItem = new QTreeWidgetItem();
			contactsItem->setText(0, tr("陌生人x3"));
			contactsItem->setIcon(0, QIcon(tr(":/Resources/UserFace/face.jpg")));
			contactsItem->setData(0, Qt::UserRole + 1, 1);
			groupItem->addChild(contactsItem);
		}
	}

    {
        m_searchButton = new QToolButton();
        m_searchButton->setObjectName("searchButton");
        m_searchButton->setCursor(Qt::ArrowCursor);

        QHBoxLayout *search_layout = new QHBoxLayout();
        search_layout->addStretch();
        search_layout->addWidget(m_searchButton);
        search_layout->setSpacing(0);
        search_layout->setContentsMargins(0, 0, 5, 0);
        ui.searchEdit->setLayout(search_layout);
        ui.searchEdit->setTextMargins(3, 3, 3, 3);
	}
}

AirIM::~AirIM()
{
//    m_searchButton->deleteLater();
}

void AirIM::paintEvent(QPaintEvent* /*event*/)
{
    QStyleOption opt;
    opt.init(this);
    QPainter p(this);
    p.setRenderHint(QPainter::Antialiasing);

#ifdef Q_OS_WIN32
    if (!IsZoomed((HWND)this->effectiveWinId()))
    {
        p.setPen(Qt::NoPen);
        p.setBrush(QColor(22, 154, 218));
        p.drawRoundedRect(this->rect().left()+6, this->rect().top()+6, this->rect().width()-12, this->rect().height()-12, 2, 2);

        p.setBrush(QColor(255, 255, 255, 192));
        QPoint footerShortcutsPoint = ui.footerShortcuts->mapToParent(QPoint(ui.footerShortcuts->rect().x(), ui.footerShortcuts->rect().y()));
        QPainterPath path;
        path.setFillRule(Qt::WindingFill);
        path.addRoundedRect(footerShortcutsPoint.x(), footerShortcutsPoint.y(), ui.footerShortcuts->rect().width(), ui.footerShortcuts->rect().height(), 1, 1);
        path.addRect(footerShortcutsPoint.x(), footerShortcutsPoint.y(), ui.footerShortcuts->rect().width(), 4); // lefttop & righttop corner not rounded
        p.drawPath(path.simplified() ); // Only leftbottom & rightbottom right corner rounded

        style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
    }
    else
#endif
    {
        p.fillRect(this->rect(), QColor(22, 154, 218));
        QPoint footerShortcutsPoint = ui.footerShortcuts->mapToParent(QPoint(ui.footerShortcuts->rect().x(), ui.footerShortcuts->rect().y()));
        p.fillRect(footerShortcutsPoint.x(), footerShortcutsPoint.y(), ui.footerShortcuts->rect().width(), ui.footerShortcuts->rect().height(), QColor(255, 255, 255, 192));
    }
}

#ifdef Q_OS_WIN32
bool AirIM::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
    if (eventType == "windows_generic_MSG")
    {
        MSG* msg = (MSG*)message;
        switch(msg->message)
        {
        case WM_NCHITTEST:
            {
                if (!this->isMaximized() && !this->isFullScreen())
                {
                    int xPos = GET_X_LPARAM(msg->lParam) - this->frameGeometry().x();
                    int yPos = GET_Y_LPARAM(msg->lParam) - this->frameGeometry().y();
                    int nBorderWidth = 8;
                    int nBorderRadius = 8;
                    QWidget* widget = this->childAt(xPos, yPos);
                    if (xPos < nBorderRadius && yPos < nBorderRadius)
                    {
                        *result = HTTOPLEFT;
                    }
                    else if (xPos < nBorderRadius && yPos > this->height() - nBorderRadius)
                    {
                        *result = HTBOTTOMLEFT;
                    }
                    else if (xPos > this->width() - nBorderRadius && yPos < nBorderRadius)
                    {
                        *result = HTTOPRIGHT;
                    }
                    else if (xPos > this->width() - nBorderRadius && yPos > this->height() - nBorderRadius)
                    {
                        *result = HTBOTTOMRIGHT;
                    }
                    else if (xPos < nBorderWidth)
                    {
                        *result = HTLEFT;
                    }
                    else if (yPos < nBorderWidth)
                    {
                        *result = HTTOP;
                    }
                    else if (yPos > this->height() - nBorderWidth)
                    {
                        *result = HTBOTTOM;
                    }
                    else if (xPos > this->width() - nBorderWidth)
                    {
                        *result = HTRIGHT;
                    }
                    else if (widget == nullptr
                             || widget->objectName() == "titleLabel" || widget->objectName() == "centralWidget" || widget->objectName() == "nicknameLabel"
                             || widget->objectName() == "footerShortcuts")
                    {
                        *result = HTCAPTION;
                    }
                    else
                    {
                        return false;
                    }

                    return true;
                }
                else
                {
                    int xPos = GET_X_LPARAM(msg->lParam) - this->frameGeometry().x();
                    int yPos = GET_Y_LPARAM(msg->lParam) - this->frameGeometry().y();
                    QWidget* widget = this->childAt(xPos, yPos);
                    if (widget == nullptr
                            || widget->objectName() == "titleLabel" || widget->objectName() == "centralWidget" || widget->objectName() == "nicknameLabel"
                            || widget->objectName() == "footerShortcuts")
                    {
                        *result = HTCAPTION;
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            break;

        case WM_GETMINMAXINFO:
            {
                MINMAXINFO *lpMMI = (MINMAXINFO*)msg->lParam;
                QDesktopWidget desktopWidget;
                QRect desktop = desktopWidget.availableGeometry();
                lpMMI->ptMaxSize.x = desktop.width();
                lpMMI->ptMaxSize.y = desktop.height();
                lpMMI->ptMaxPosition.x = desktop.x();
                lpMMI->ptMaxPosition.y = desktop.y();
                lpMMI->ptMinTrackSize.x = 255; // minimum width for your window
                lpMMI->ptMinTrackSize.y = 540; // minimum height for your window
                lpMMI->ptMaxTrackSize.x = desktop.width();
                lpMMI->ptMaxTrackSize.y = desktop.height();

                result = 0;
                return true;
            }
            break;
        }
    }

	return false;  
}

void AirIM::changeEvent(QEvent* event)
{
	if (event->type() == QEvent::WindowStateChange)
	{
		//QWindowStateChangeEvent* e = static_cast<QWindowStateChangeEvent*>(event);
		if (isMinimized())
		{
			// MINIMIZED
		}
		else if (isMaximized())
		{
			// MAXIMIZED
			//ui.maximizeButton->show();
			//ui.restoreButton->show();
            ui.maximizeSysButton->setProperty("windowMaxsized", true);
			//ui.maximizeButton->style()->unpolish(ui.maximizeButton);
            ui.maximizeSysButton->style()->polish(ui.maximizeSysButton);
			//ui.maximizeButton->ensurePolished();
            ui.maximizeSysButton->update();
            ui.centralWidget->setContentsMargins(0, 0, 0, 0);
		}
		else
		{
			// Restore
			//ui.maximizeButton->show();
			//ui.maximizeButton->hide();
            ui.maximizeSysButton->setProperty("windowMaxsized", false);
			//ui.maximizeButton->style()->unpolish(ui.maximizeButton);
            ui.maximizeSysButton->style()->polish(ui.maximizeSysButton);
			//ui.maximizeButton->ensurePolished();
            ui.maximizeSysButton->update();
            ui.centralWidget->setContentsMargins(6, 6, 6, 6);
		}
	}

}
#endif

#ifdef Q_OS_WIN32
void AirIM::trayActived(QSystemTrayIcon::ActivationReason activeReason)
{
    if (activeReason == QSystemTrayIcon::Trigger || activeReason == QSystemTrayIcon::DoubleClick)
    {
        taryOpenMain();
    }
    else if (activeReason == QSystemTrayIcon::MiddleClick)
    {
        //QMessageBox::information(this, tr("托盘消息"), tr("鼠标中键"));
    }
}

void AirIM::taryOpenMain()
{
	// 恢复窗口显示
	this->show();
	//m_pLoginDlg->setFixedSize(380, 292);
}

void AirIM::trayClose()
{
#ifdef Q_OS_WIN32
    qApp->quit();
#else
    this->close();
#endif
}

void AirIM::on_minisizeSysButton_clicked()
{
    this->hide();
}

void AirIM::on_maximizeSysButton_clicked()
{
	if (isMaximized())
	{
		// Restore
		this->showNormal();
	}
	else
	{
		// Maxsize
		this->showMaximized();
	}
}

void AirIM::on_closeSysButton_clicked()
{
    //this->close();
    qApp->quit();
}
#endif

void AirIM::on_searchEdit_textChanged(const QString text)
{
    if (text.isEmpty())
    {
        m_searchButton->show();
    }
    else
    {
        m_searchButton->hide();
    }
}

void AirIM::returnPressed()
{
	//ui.statusMessageEdit->hasFocus()
	setFocus();
}

void AirIM::editingFinished()
{
    ui.signatureEdit->home(false);
}

void AirIM::contactsTreeWidget_clicked(const QModelIndex& index)
{
	int nType = index.data(Qt::UserRole + 1).toInt();				// 类型
	if (nType == 0)
	{
		if (ui.treeWidgetContacts->isExpanded(index))
		{
			ui.treeWidgetContacts->setExpanded(index, false);
		} 
		else
		{
			ui.treeWidgetContacts->setExpanded(index, true);
		}
	}
}

void AirIM::contactsTreeWidget_doubleClicked(const QModelIndex& index)
{
    int nType = index.data(Qt::UserRole + 1).toInt();				// 类型
    if (nType == 1)
    {
        //  显示聊天窗口Chat
//        DisplayRole			// 昵称
//        DecorationRole		// 头像
//        UserRole + 1		// 类型，是否是组名0，好友1，公众号2等标识
//        UserRole + 2		// 账号(唯一标识)
//        UserRole + 3		// 备注名
//        UserRole + 4		// 个性签名
        QString strAccount = index.data(Qt::DisplayRole).toString();	// 账号
        QString strNickName = index.data(Qt::UserRole + 1).toString();	// 昵称
        Chat* c = new Chat;
        c->show();
    }
}

void AirIM::on_tabButtonRecentContacts_toggled(bool checked)
{
	if (checked)
	{
		int oldCheck = ui.stackedWidget->currentIndex();
		ui.stackedWidget->setCurrentIndex(0);
		QRect rc = ui.listWidgetRecentContacts->geometry();
		QPropertyAnimation *anim2 = new QPropertyAnimation(ui.listWidgetRecentContacts, "geometry");
		anim2->setDuration(200);
		if (oldCheck < ui.stackedWidget->currentIndex())
		{
			anim2->setStartValue(QRect(rc.right(), rc.top(), rc.width(), rc.height()));
		}
		else
		{
			anim2->setStartValue(QRect(rc.left() - rc.width(), rc.top(), rc.width(), rc.height()));
		}
		anim2->setEndValue(rc);
		//anim2->setEasingCurve(QEasingCurve::OutBounce);
		anim2->start();
	}
}

void AirIM::on_tabButtonContacts_toggled(bool checked)
{
	if (checked)
	{
		int oldCheck = ui.stackedWidget->currentIndex();
		ui.stackedWidget->setCurrentIndex(1);
		QRect rc = ui.treeWidgetContacts->geometry();
		QPropertyAnimation *anim2 = new QPropertyAnimation(ui.treeWidgetContacts, "geometry");
		anim2->setDuration(200);
		if (oldCheck < ui.stackedWidget->currentIndex())
		{
			anim2->setStartValue(QRect(rc.right(), rc.top(), rc.width(), rc.height()));
		}
		else
		{
			anim2->setStartValue(QRect(rc.left()-rc.width(), rc.top(), rc.width(), rc.height()));
		}
		anim2->setEndValue(rc);
		//anim2->setEasingCurve(QEasingCurve::OutBounce);
		anim2->start();
	}
}

void AirIM::on_tabButtonGroups_toggled(bool checked)
{
	if (checked)
	{
		int oldCheck = ui.stackedWidget->currentIndex();
		ui.stackedWidget->setCurrentIndex(2);
		QRect rc = ui.treeWidgetGroups->geometry();
		QPropertyAnimation *anim2 = new QPropertyAnimation(ui.treeWidgetGroups, "geometry");
		anim2->setDuration(200);
		if (oldCheck < ui.stackedWidget->currentIndex())
		{
			anim2->setStartValue(QRect(rc.right(), rc.top(), rc.width(), rc.height()));
		}
		else
		{
			anim2->setStartValue(QRect(rc.left() - rc.width(), rc.top(), rc.width(), rc.height()));
		}
		anim2->setEndValue(rc);
		//anim2->setEasingCurve(QEasingCurve::OutBounce);
		anim2->start();

	}
}

void AirIM::socketConnected()
{

}

void AirIM::socketDisconnected()
{

}

void AirIM::socketError(QAbstractSocket::SocketError /*socketErr*/)
{

}

void AirIM::socketReadyRead()
{

}

void AirIM::setSocket(QTcpSocket* s)
{
    Q_ASSERT(m_socket == nullptr && s != nullptr);
    m_socket = s;

    // socket 信号槽
    connect(m_socket, SIGNAL(connected()), this, SLOT(socketConnected()));
    connect(m_socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
    connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
    connect(m_socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead()));
}
